package com.simplegui.examples.pong;

import static com.simplegui.examples.pong.PongConfigurations.*;

import java.awt.Color;
import java.awt.Point;
import java.util.Random;

import com.simplegui.api.Canvas;
import com.simplegui.api.GameComponent;

public class Ball implements GameComponent{
	
	public final double radius;
	
	private Pong pong;
	private double[] position = new double[2];
	private double[] velocity = new double[2];
	
	public Ball(Pong pong) {
		super();
		radius = 20;
		this.pong = pong;
	}

	public void resetBall(boolean goToRight) {
		position[0] = FRAME_WIDTH / 2;
		position[1] = FRAME_HEIGHT / 2;
		
		//generate a random velocity
		Random random = new Random();
		double x =  new Integer(random.nextInt(120) + 120).doubleValue() / 100;
		double y = -new Integer(random.nextInt(120) + 60).doubleValue() / 100;

		// setup the right direction
		if (!goToRight) x *= -1;

		velocity[0] = x;
		velocity[1] = y;
	}

	@Override
	public void executeLogic() {
		// Update ball position
		position[0] += velocity[0];
		position[1] += velocity[1];

		// collide and reflect on top of canvas
		if (position[1] <= radius){
			executeSound();
			velocity[1] = - velocity[1];
		}

		// collide and reflect on bottom of canvas
		if (position[1] >= FRAME_HEIGHT - radius){
			executeSound();
			velocity[1] = - velocity[1];
		}
		

		//tests whether the ball touches with the left gutter
		Paddle leftPaddle = pong.getLeftPaddle();
		if (position[0] <= radius + leftPaddle.getWidth() ){
			//tests whether the ball touches with the left paddle
			int[] ballLimits = {new Double(position[1]).intValue() - (int)radius, new Double(position[1]).intValue() + (int)radius}; 
			int[] padleLimits = {leftPaddle.getTopPosition(), leftPaddle.getTopPosition() + leftPaddle.getHeight()};
			if (ballLimits[1] < padleLimits[0] || ballLimits[0] > padleLimits[1]){
				//dont touches the paddle
				pong.getScore().incrementScore2();
				resetBall(true);
			}else{
				//touches the paddle, so, reflect the ball increasing ball velocity in 10%
				executeSound();
				velocity[0] = - (velocity[0] * 0.1 + velocity[0]);				        	
			}

		}
		
		//tests whether the ball touches with the right gutter
		Paddle rightPaddle = pong.getRightPaddle();
		if (position[0] >= FRAME_WIDTH - radius - rightPaddle.getWidth()){
			//tests whether the ball touches with the right paddle
			int[] ballLimits = {new Double(position[1]).intValue() - (int)radius, new Double(position[1]).intValue() + (int)radius}; 
			int[] padleLimits = {rightPaddle.getTopPosition(), rightPaddle.getTopPosition() + rightPaddle.getHeight()};
			if (ballLimits[1] < padleLimits[0] || ballLimits[0] > padleLimits[1]){
				//dont touches the paddle
				pong.getScore().incrementScore1();
				resetBall(false);
			}else{
				//touches the paddle, so, reflect the ball increasing ball velocity in 10%
				executeSound();
				velocity[0] = - (velocity[0] * 0.1 + velocity[0]);
			}
		}

	}
	
	private void executeSound() {
		pongSound.rewind();
		pongSound.play();
	}
	
	public double[] getBallPos() {
		return position;
	}

	public double[] getBallVel() {
		return velocity;
	}
	
	public double getRadius() {
		return radius;
	}

	@Override
	public void draw(Canvas c) {
		c.drawCircle(new Point(new Double(getBallPos()[0]).intValue(), new Double(getBallPos()[1]).intValue()), (int)getRadius(), 2, Color.GRAY, Color.WHITE);
	}

	@Override
	public Point getPosition() {
		return new Point((int)position[0], (int)position[1]);
	}
	
}
